package main.bots;

import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import main.client;
import main.constants.Constants;
import main.listeners.PaintHandler;
import main.listeners.ServerMessagesHandler;
import main.scripts.Combat;
import main.scripts.PestControl;
import main.scripts.Thieving;

public class ScriptManager implements Runnable {
	
	public static Bot botRunning = null;
	public static ScriptManager scriptM = null;
	public static Thread thread;
	

	public static Map<String, Bot> BotMap = new HashMap<String, Bot>();
	public static ArrayList<File> botFiles = new ArrayList<File>();
	public static boolean setBots = false;
	private static InputStream input;
	private static DataInputStream data;
	public static boolean paused = false;
	public ScriptManager() {
	
	}
	public void pauseCurrentScript() {
		paused = !paused;
	}
	public static void stopCurrentScript() {
		if(botRunning == null)
			return;
		botRunning.onFinish();
		botRunning = null;
	}
	public synchronized static void setBots() {
		if(setBots)
			return;
	
			getFiles();
			
//		BotMap.put(Constants.BOT_COMBAT_NAME, new Combat());			
//		BotMap.put(Constants.BOT_THIEVING_NAME, new Thieving());
//			BotMap.put("pest control", new PestControl());
			setBots = true;
		} 
		
	

	@SuppressWarnings({ "deprecation", "unchecked" })
	private synchronized static void getFiles() {
		if(setBots)
			return;
		
		File[] dir = new File("./main/scripts").listFiles();
		URL[] scriptURLS = new URL[100];
		int z = 0;
		for(File f : dir) {
			try {
				if(!f.getName().contains(".class")) continue;
				if(f.getName().contains("$")) continue;
				scriptURLS[z] = f.toURL();
				z++;
				System.out.println("Found: " + f.getName());
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
		
		ClassLoader loader = new URLClassLoader(scriptURLS);
		try {
			for(URL u : scriptURLS) {
				if(u == null) continue;
				String fileName = u.getFile();
				int beginIndex = fileName.indexOf("scripts/") + 8;
				int endIndex = fileName.indexOf(".c");
				fileName = fileName.substring(beginIndex, endIndex);
				System.out.println("Attempting to load: " + fileName);
		Class<Bot> c = (Class<Bot>) loader.loadClass("main.scripts."+fileName);
		if(c == null) {
			System.out.println("NULL");
			continue;
		}
		
		Object instance = c.newInstance();
		Method m = c.getMethod("getScriptName");
		
		String name = (String)m.invoke(instance);
		if(BotMap.containsKey(name)) continue;
		BotMap.put(name, c.newInstance());
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
		
		
		
		
	
		   
	}
	public static void processScript() {
		while(botRunning == null) { //don't do anything pl0x
			try {
				Thread.sleep(Constants.SCRIPTMANAGER_THREAD_SLEEPTIME);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}	
			}
		if(botRunning.onStart()) {
			System.out.println("Running Version: " + botRunning.getVersion());
		} else {
			System.out.println("ERROR! SCRIPT DID NOT START");
			botRunning = null;
			return;
		}
		System.out.println("Running script on thread: " + Thread.currentThread().getName());
		while(botRunning != null && !botRunning.endCondition()) { //Don't stop yet plox
			//PaintHandler.callRepaint();
			if(paused ) continue;
			
			System.out.println("Loading int: " + Methods.getClientToUse().loadingStage);
			if(!Methods.getClientToUse().loggedIn) {
				Methods.getClientToUse().loginMethod(Methods.getClientToUse().myUsername, Methods.getClientToUse().myPassword, false);
				try {
					Thread.sleep(7000);
					continue;
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				continue;
			}
			if(Methods.getClientToUse().loadingStage != 2) {
				System.out.println("Waiting...");
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				continue;
			}
//			if(Methods.getClientToUse().loadingStage != 0) {
//				System.out.println("Detecting loading, wating");
//				try {
//					Thread.sleep(5000);
//				} catch (InterruptedException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
//				continue;
//			}
				try {
					
					EventHandler.callEvents();
					Thread.sleep(botRunning.loop());
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				EventHandler.callEvents();
		}
		stopCurrentScript();
		PaintHandler.toPaint = null;
		ServerMessagesHandler.listeners = null; 
		processScript();
		
	}
	
	public static void startBot(String s) {
		botRunning = BotMap.get(s);
		if(botRunning == null) {
			System.out.println("Bot Is null sorry!");
			return;
		}
//		if(botRunning.onStart()) {
//			System.out.println("Running Version: " + botRunning.getVersion());
//		} else {
//			System.out.println("ERROR! SCRIPT DID NOT START");
//			botRunning = null;
//		}
	}
	public static void startBot(Bot b) {
		botRunning = b;
	}
	public static ScriptManager getScriptManager() {
		if(scriptM == null) {
			System.out.println("Setting ScriptManager up..");
			scriptM = new ScriptManager();
			thread = new Thread(scriptM);
			thread.start();	
			setBots();
		}
		return scriptM;
	}
	@Override
	public void run() {
		System.out.println("Script Manager Thread Started, Thread: " + Thread.currentThread().getName());
		Thread.currentThread().setName("ScriptManager");
	
		processScript();
	}

}
